using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Dynamic; using System.Reflection; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var employee = (new Employee()).AsDynamic(); employee.Name = "Paul van Brenk"; employee.Age = 30; Console.WriteLine("Employee {0} is {1} years old.", employee.Name, employee.Age); Console.ReadLine(); } } static class DynamicHelper { public static dynamic AsDynamic(this T source) { return new DynamicReflection(source); } class DynamicReflection : DynamicObject { public DynamicReflection(T source) : base() { this.Source = source; } public override bool TrySetMember(SetMemberBinder binder, object value) { // find the member MemberInfo member; if (!TryFindMember(binder.Name, out member)) { return false; } // we can only set values to fields and properties // using reflection switch (member.MemberType) { /* todo: check the type of the incoming value and the type of the property. */ case (MemberTypes.Field): ((FieldInfo)member).SetValue(Source, value); return true; case (MemberTypes.Property): ((PropertyInfo)member).SetValue(Source, value,/*ndex*/ null); // we don't support indexed properties return true; } // didn't work return false; } public override bool TryGetMember(GetMemberBinder binder, out object result) { // find the member MemberInfo member; if (!TryFindMember(binder.Name, out member)) { result = null; return false; } // we can only set values to fields and properties // using reflection switch (member.MemberType) { /* todo: check the type of the incoming value and the type of the property. */ case (MemberTypes.Field): result = ((FieldInfo)member).GetValue(Source); return true; case (MemberTypes.Property): result = ((PropertyInfo)member).GetValue(Source,/*ndex*/ null); // we don't support indexed properties return true; } // didn't work result = null; return false; } private bool TryFindMember(string name, out MemberInfo memberInfo) { // find the member var members = Type.GetMember(name, MemberTypes.All, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); // more than 1 not supported for now if (members.Length != 1) { memberInfo = null; return false; } memberInfo = members[0]; return true; } private Type Type { get { return typeof(T); } } public T Source { get; private set; } } } class Employee { public Employee() { } private string name; private int age { get; set; } private void AddYears(int count) { this.age += count; } public void Display() { Console.WriteLine("name {0}, age {1}", name, age); } } }